package com.wait.onlinepicture.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wait.onlinepicture.exception.BusinessException;
import com.wait.onlinepicture.exception.ErrorCode;
import com.wait.onlinepicture.mapper.PictureCommentMapper;
import com.wait.onlinepicture.model.dto.comment.CommentAddRequest;
import com.wait.onlinepicture.model.dto.comment.CommentQueryRequest;
import com.wait.onlinepicture.model.dto.comment.CommentReviewRequest;
import com.wait.onlinepicture.model.entity.Picture;
import com.wait.onlinepicture.model.entity.PictureComment;
import com.wait.onlinepicture.model.entity.User;
import com.wait.onlinepicture.model.enums.UserRoleEnum;
import com.wait.onlinepicture.model.vo.CommentVO;
import com.wait.onlinepicture.model.vo.user.UserVO;
import com.wait.onlinepicture.service.CommentService;
import com.wait.onlinepicture.service.PictureService;
import com.wait.onlinepicture.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Wait葡萄成熟时
 * @description 针对表【picture_comment(图片评论)】的数据库操作Service实现
 * @createDate 2025-09-26 14:00:00
 */
@Service
@Slf4j
public class CommentServiceImpl extends ServiceImpl<PictureCommentMapper, PictureComment>
        implements CommentService {

    @Resource
    private UserService userService;

    @Resource
    private PictureService pictureService;

    /**
     * description 创建评论
     * author Wait葡萄成熟时
     * date 下午2:00 2025/9/26
     */
    @Override
    public long addComment(CommentAddRequest commentAddRequest, User loginUser) {
        if (commentAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        
        Long pictureId = commentAddRequest.getPictureId();
        String content = commentAddRequest.getContent();
        Long parentId = commentAddRequest.getParentId();
        
        // 校验参数
        if (pictureId == null || pictureId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "图片ID不合法");
        }
        if (StringUtils.isBlank(content)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "评论内容不能为空");
        }
        if (content.length() > 1024) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "评论内容过长");
        }
        
        // 校验图片是否存在
        Picture picture = pictureService.getById(pictureId);
        if (picture == null || picture.getIsDelete() == 1) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "图片不存在");
        }
        
        // 校验父评论是否存在
        if (parentId != null && parentId > 0) {
            PictureComment parentComment = this.getById(parentId);
            if (parentComment == null || parentComment.getIsDelete() == 1) {
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "父评论不存在");
            }
        }
        
        // 创建评论
        PictureComment pictureComment = new PictureComment();
        pictureComment.setPictureId(pictureId);
        pictureComment.setUserId(loginUser.getId());
        pictureComment.setContent(content);
        pictureComment.setParentId(parentId != null ? parentId : 0L);
        
        // 管理员发布的评论自动审核通过
        if (UserRoleEnum.ADMIN.getValue().equals(loginUser.getUserRole())) {
            pictureComment.setReviewStatus(1);
            pictureComment.setReviewerId(loginUser.getId());
            pictureComment.setReviewTime(new Date());
        } else {
            pictureComment.setReviewStatus(0);
        }
        
        boolean result = this.save(pictureComment);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "评论创建失败");
        }
        
        return pictureComment.getId();
    }

    /**
     * description 删除评论
     * author Wait葡萄成熟时
     * date 下午2:00 2025/9/26
     */
    @Override
    public boolean deleteComment(long id, User loginUser) {
        // 校验评论是否存在
        PictureComment comment = this.getById(id);
        if (comment == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "评论不存在");
        }
        
        // 仅评论创建者和管理员可删除
        if (!comment.getUserId().equals(loginUser.getId()) && 
            !UserRoleEnum.ADMIN.getValue().equals(loginUser.getUserRole())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        
        return this.removeById(id);
    }

    /**
     * description 审核评论
     * author Wait葡萄成熟时
     * date 下午2:00 2025/9/26
     */
    @Override
    public boolean reviewComment(CommentReviewRequest commentReviewRequest, User loginUser) {
        if (commentReviewRequest == null || commentReviewRequest.getId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        
        // 校验评论是否存在
        Long id = commentReviewRequest.getId();
        PictureComment comment = this.getById(id);
        if (comment == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "评论不存在");
        }
        
        // 设置审核信息
        comment.setReviewStatus(commentReviewRequest.getReviewStatus());
        comment.setReviewMessage(commentReviewRequest.getReviewMessage());
        comment.setReviewerId(loginUser.getId());
        comment.setReviewTime(new Date());
        
        return this.updateById(comment);
    }

    /**
     * description 获取评论VO
     * author Wait葡萄成熟时
     * date 下午2:00 2025/9/26
     */
    @Override
    public CommentVO getCommentVO(PictureComment pictureComment) {
        if (pictureComment == null) {
            return null;
        }
        
        CommentVO commentVO = new CommentVO();
        BeanUtils.copyProperties(pictureComment, commentVO);
        
        // 关联查询用户信息
        Long userId = pictureComment.getUserId();
        User user = null;
        if (userId != null && userId > 0) {
            user = userService.getById(userId);
        }
        
        UserVO userVO = userService.getUserVO(user);
        commentVO.setUser(userVO);
        
        return commentVO;
    }

    /**
     * description 获取评论VO列表
     * author Wait葡萄成熟时
     * date 下午2:00 2025/9/26
     */
    @Override
    public List<CommentVO> getCommentVOList(List<PictureComment> pictureCommentList) {
        if (CollUtil.isEmpty(pictureCommentList)) {
            return new ArrayList<>();
        }
        return pictureCommentList.stream().map(this::getCommentVO).collect(Collectors.toList());
    }

    /**
     * description 分页获取评论列表
     * author Wait葡萄成熟时
     * date 下午2:00 2025/9/26
     */
    @Override
    public List<CommentVO> listCommentVOByPage(CommentQueryRequest commentQueryRequest) {
        if (commentQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        
        QueryWrapper<PictureComment> queryWrapper = getQueryWrapper(commentQueryRequest);
        long current = commentQueryRequest.getCurrent();
        long pageSize = commentQueryRequest.getPageSize();
        
        // 限制爬虫
        if (pageSize > 100) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        
        // 分页查询
        Page<PictureComment> commentPage = this.page(new Page<>(current, pageSize), queryWrapper);
        List<PictureComment> commentList = commentPage.getRecords();
        
        return getCommentVOList(commentList);
    }

    /**
     * description 用于将查询请求转为 QueryWrapper 对象的方法
     * author Wait葡萄成熟时
     * date 下午2:00 2025/9/26
     */
    @Override
    public QueryWrapper<PictureComment> getQueryWrapper(CommentQueryRequest commentQueryRequest) {
        if (commentQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
        }
        
        Long id = commentQueryRequest.getId();
        Long pictureId = commentQueryRequest.getPictureId();
        Long userId = commentQueryRequest.getUserId();
        Long parentId = commentQueryRequest.getParentId();
        Integer reviewStatus = commentQueryRequest.getReviewStatus();
        String sortField = commentQueryRequest.getSortField();
        String sortOrder = commentQueryRequest.getSortOrder();
        
        QueryWrapper<PictureComment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("isDelete", 0);
        queryWrapper.eq(ObjUtil.isNotNull(id), "id", id);
        queryWrapper.eq(ObjUtil.isNotNull(pictureId), "pictureId", pictureId);
        queryWrapper.eq(ObjUtil.isNotNull(userId), "userId", userId);
        queryWrapper.eq(ObjUtil.isNotNull(parentId), "parentId", parentId);
        queryWrapper.eq(ObjUtil.isNotNull(reviewStatus), "reviewStatus", reviewStatus);
        queryWrapper.orderBy(StrUtil.isNotEmpty(sortField), sortOrder.equals("ascend"), sortField);
        
        return queryWrapper;
    }
}